package cn.anoxia.springframework.beans.support;

import cn.anoxia.springframework.beans.BeansException;
import cn.anoxia.springframework.beans.factory.FactoryBean;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * The class FactoryBeanRegistrySupport.
 * <p>
 * Description:
 *
 * @author: huangle
 * @since: 2021/08/27 16:40
 */
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry{

  private final Map<String,Object> factoryBeanObjectCache = new ConcurrentHashMap<>();

  protected Object getCachedObjectForFactoryBean(String name){
    Object o = this.factoryBeanObjectCache.get(name);
    return o != NULL_OBJECT ? o : null;
  }

  protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName) throws BeansException {
    if (factory.isSingleton()) {
      Object object = this.factoryBeanObjectCache.get(beanName);
      if (object == null) {
        object = doGetObjectFromFactoryBean(factory, beanName);
        this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
      }
      return (object != NULL_OBJECT ? object : null);
    } else {
      return doGetObjectFromFactoryBean(factory, beanName);
    }
  }

  private Object doGetObjectFromFactoryBean(final FactoryBean factory, final String beanName) throws BeansException {
    try {
      return factory.getObject();
    } catch (Exception e) {
      throw new BeansException("FactoryBean threw exception on object[" + beanName + "] creation", e);
    }
  }

}
